Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Core] Base python solver #2068

Merged
merged 20 commits into from
May 29, 2018
Merged

[Core] Base python solver #2068

merged 20 commits into from
May 29, 2018

Conversation

philbucher
Copy link
Member

This PR adds a baseclass for the python solvers to the core. This is the second step after having the AnalysisStage now
I used the functions that are currently used in the FluidDynamics and the StructuralMechanics Solver and put them to the base-class

This PR is to discuss the interface, I think/hope that it will not be so difficult this time since I am not really doing new things and only collected what exists already

After an agreement has been reached I will add documentation and finish integrating it in the Structural Solver

Having this base class will allow us to call all the functions in the interface in the stage without having to check if a solver actually implements them

Note that I didn't include Solve since after @RiccardoRossi s explanation we should call the functions separately
Also I did not include ImportModelPart, this one is splitted into ReadModelPart and PrepareModelPartForSolver
The first one is common for the solvers and will not have to be overwritten in most derived solvers.
The second is specific to the solvers and does what the name suggests
This separation is needed one one hand to have the reading implemented only once and also in case the Solver should not read the modelpart (used by the optimization guys)

def ComputeDeltaTime(self):
pass

def Initialize(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can agree that the strategies will called in this cases, and then we can call this methods on the strategy

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I intentionally left this empty since theoretically a solver can have no strategy

e.g. an FSI solver does not have a strategy itself

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you mean that it cannot have a strategy inside? it may even have multiple as long as they are hidden in the api...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it can have 0 to n strategies inside, that why I left it empty

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry i misread what you wrote.

def AdvanceInTime(self):
pass

def ComputeDeltaTime(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can return the current delta time

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, good suggestion, esp for the structure since it cannot compute Dt yet

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this function on the external interface of the base class? I don't think it is used outside of the solver right now, and we could think of solvers that don't have it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also true
Will remove it, the user should call AdvanceInTime

def AddDofs(self):
pass

def GetMinimumBufferSize(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can return 2 at least

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why 2?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a default, the minimum buffer size. Obviously the idea is to override in the solvers


def ReadModelPart(self):
# TODO replace the functions in the solvers in Fluid and Structure
KratosMultiphysics.Logger.PrintInfo("::[PythonSolver]::", "Reading model part.")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I was wondering is if we should "hard-code" labels like this. If we call it from a derived solver, is it more useful for the label to be "[PythonSolver]" or "[DynamicStructuralSolver]"? I don't have a strong opinion on this, but it is a discussion I think we should have at some point.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thing, I remember or something... That in my analysis I added a method to return the label, that is overrided in each solver, so the solver always knows the name of the solver

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be easy to add a GetSolverName function that every solver implements

Might be useful if several solvers are used, which is likely to be the case in the future

I dont habe a strong opinion though

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another point for hardcoding is that if a solver calls the functions of the baseclass (e.g. Initialize) then we would have multiple Initializing done prints with the same solver name which I think would be quite confusing

KratosMultiphysics.Logger.PrintInfo("ModelPart", self.main_model_part)
KratosMultiphysics.Logger.PrintInfo("::[PythonSolver]:: ", "Finished reading model part.")

def PrepareModelPartForSolver(self):
Copy link
Member

@jcotela jcotela May 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, does this need to be a public method of the solver? Or should it work internally? Also, the name is a bit strange... If we are "the solver", why should we prepare something "for the solver"?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is good it is a public method, since one may want to override it. an example is if you have a "strange" problem and you need to build submodelparts on your own

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be public
For fluids this is the function that would replace the elements, whereas in structure we e.g. assign the materials

Copy link
Member

@RiccardoRossi RiccardoRossi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i am making minor comments.

another one is that
def validate_and_transfer_matching_settings

i guess should be done in c++ with its own tests etc

def AddDofs(self):
pass

def GetMinimumBufferSize(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for a static solver, 1 is enough...

KratosMultiphysics.Logger.PrintInfo("ModelPart", self.main_model_part)
KratosMultiphysics.Logger.PrintInfo("::[PythonSolver]:: ", "Finished reading model part.")

def PrepareModelPartForSolver(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is good it is a public method, since one may want to override it. an example is if you have a "strange" problem and you need to build submodelparts on your own

def GetMinimumBufferSize(self):
pass

def ReadModelPart(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if we call this ImportModelPart, exactly with the implementation and you propose...that is, also followed by a function "Prepare"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine for me

I used a different name because others (e.g. the FSI solvers) are still using ImportModelPart and I would have silently broken those

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this argument makes sense.

def ComputeDeltaTime(self):
pass

def Initialize(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you mean that it cannot have a strategy inside? it may even have multiple as long as they are hidden in the api...

def Clear(self):
pass

def GetComputingModelPart(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to say that i invented this ComputingModelPart idea...and i hate it :-(.

I don't have a better idea however

@philbucher
Copy link
Member Author

I finished the base-class and the adaption of the Structural Solvers
=> ready to be properly reviewed

I ran the tests for the involved applications

@jcotela I tried to do it also for the Fluid but there is a bit of refactoring needed, so I would prefer if it would be done in a separate PR

@jcotela
Copy link
Member

jcotela commented May 17, 2018

@philbucher I'll make a pass of refactoring for fluid solvers once this is merged.

@philbucher
Copy link
Member Author

ping @KratosMultiphysics/technical-committee

@philbucher
Copy link
Member Author

ping @KratosMultiphysics/technical-committee I added the wiki for the AnalysisStage and the PythonSolver

Please have a look such that we can proceed with this and #2135

"""
pass

def Check(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add some trivial checks (like settings is a Parameter, input file exists, etc.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the type of the input is checked in the constructor

I thought of this function to be called before the SolutionLoop (I will add it to the AnalysisStage)
=> It should call methods like Strategy.Check() to validate if the input is correct

Therefore it cannot validate if the input file has been found
(btw for this one the error is quite clear already:
RuntimeError: Error: Error opening mdpa file : Example.mdpa)

@philbucher
Copy link
Member Author

philbucher commented May 25, 2018

I did the modifications as requested by @RiccardoRossi => passing the Model instead of the ModelPart to the solver

@KratosMultiphysics/technical-committee please have a look since this has to be merged before #2135

After this is merged I will solve the "conflicts" in #2135 to finalize everything

loumalouomega
loumalouomega previously approved these changes May 26, 2018
@loumalouomega
Copy link
Member

@philbucher feel free to merge both #2135 and this PR

RiccardoRossi
RiccardoRossi previously approved these changes May 27, 2018
Copy link
Member

@RiccardoRossi RiccardoRossi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i am approving. @philbucher wait if someone blocks it tomorrow in the morning and otherwise merge...

@@ -95,7 +95,7 @@ def ExportModelPart(self):
file.close()
KratosMultiphysics.ModelPartIO(name_out_file, KratosMultiphysics.IO.WRITE).WriteModelPart(self.main_model_part)

def AdvanceInTime(self):
def AdvanceInTime(self, current_time):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

current time can be obtained as

  model_part.ProcessInfo[TIME]

why do you need to pass it?

@loumalouomega
Copy link
Member

@philbucher I have been doing experiments with a branch, merging this PR and #2135, and for example the fluid does not work anymore, @jcotela do you mind if I repair that?

"""
raise Exception('Please implement "GetMinimumBufferSize" in your derived solver')

def ImportModelPart(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two of these, there is the ImportModelPart and the _ImportModelPart, why?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, deprecated, I see

@philbucher
Copy link
Member Author

@loumalouomega please wait with pushing to this Branch, I am fixing FSI and your branch before merging this

@jcotela and I know abt the problems, the fluid will be done in a separate PR before #2135

Please give me until this evening then everything should be working

@loumalouomega
Copy link
Member

Don't worry, I am working locally, but right no I am havig problems to make work the model properly with the main model part

@philbucher
Copy link
Member Author

ok, but be aware that I am also working on this

I wil push the changes regarding the solver to this branch in ~2hrs and afterwards will integrate the changes in the AnalyisStage-Pr

@philbucher philbucher dismissed stale reviews from RiccardoRossi and loumalouomega via e97f752 May 28, 2018 11:37
@philbucher
Copy link
Member Author

this is the final set of modifications
@loumalouomega @rubenzorrilla I updated your apps, the tests that run on master are still working

@KratosMultiphysics/technical-committee there were some minor things I still had to fix, in relation with #2135 , but I didn't change anything major

I will merge this branch now to #2135 to fully apply the changes there

@RiccardoRossi switching to the Model (=> #2137 ) should now only be a minor change

Copy link
Member

@loumalouomega loumalouomega left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

loumalouomega added a commit that referenced this pull request May 28, 2018
@philbucher
Copy link
Member Author

I will merge this tmr morning if none blocks/complains

@philbucher philbucher merged commit cfce65b into master May 29, 2018
@philbucher philbucher deleted the core/base-solver branch May 29, 2018 05:01
@rubenzorrilla
Copy link
Member

Apart of the fact that I did not have time to check it until now, this breaks retro compatibility (at least for the FSI app). I guess that this is something we have to live with.

In any case, it is not compatible with the current Main script generated by the interface.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants